<script>
import { getMergeInside,getColumnWidth,getRowHeight,numberToExcelColumn,excelAddressToRowCol,rowColToExcelAddress} from './utils.js';
export default {
    props:{
        helper:{
            type: Object,
            required: true
        },
        rows:{
            type: Array,
            default: () => []
        },
        cols:{
            type: Array,
            default: () => []
        },
        merges:{
            type: Array,
            default: () => []
        }
    },
    data(){
      return{
        // selections: [],
        mouseIsDown: true,
        startCell:null,
        endCell:null,
        newCells:new Map(),
        allCells:{}
      }
    },
    inject: ['CellDoubleClick','SelectionChanged',], // 注入祖先提供的方法
    computed:{
      selections(){
        if(this.startCell && this.endCell)
        {
          const [startRow,startCol] = excelAddressToRowCol(this.startCell.address)
          const [endRow,endCol] = excelAddressToRowCol(this.endCell.address)
          const selection = this.fixMergeSelection(Math.min(startRow, endRow),
          Math.min(startCol, endCol),
          Math.max(startRow, endRow),
          Math.max(startCol, endCol),this.merges);
          return selection;
        }else{
          return [-1,-1,-1,-1]
        }
      },
    },
    watch:{
      selections(a,b){
        // if(this.updatingSelection){
        //   this.$nextTick(()=>this.updatingSelection=false);
        //   return ;
        // }
        if(!(a.length === b.length && a.every((val, i) => val === b[i])))
        {
          this.SelectionChanged(a);
        }
        let c = this.helper.selection;
        if(!(a.length === c.length && a.every((val, i) => val === c[i]))){
          this.helper.selection = a; 
        }
      },
      'helper.selection'(nval){
        if(this.mouseIsDown === false){//不是在这个界面操作的
          this.startCell = this.allCells[rowColToExcelAddress(nval[0],nval[1])]
          this.endCell =  this.allCells[rowColToExcelAddress(nval[2],nval[3])];
          this.$refs.root.focus();
        }
      },
      rows(){
        this.newCells.clear();
      },
      cols(){
        this.newCells.clear();
      }
    },
    mounted(){
      document.addEventListener('mouseup',this.mouseUp);
    },
    beforeUnmount() {
      document.removeEventListener('mouseup',this.mouseUp)
    },
    methods:{
      mouseDown(){
        this.mouseIsDown=true;
        // window.addEventListener('mousemove',this.mouseMove)
      },
      mouseUp(){
        this.mouseIsDown = false;
        // window.addEventListener('mousemove',this.mouseMove)
      },
      fixMergeSelection(startRow,startCol,endRow,endCol,merges){
        for(let i in merges){
          const [start, end]= merges[i].split(":");
          const [m_startRow, m_startCol] = excelAddressToRowCol(start);
          const [m_endRow, m_endCol] = excelAddressToRowCol(end);
          //有交集
          if(!(m_startRow > endRow || m_endRow< startRow || m_startCol> endCol || m_endCol< startCol))
          {
            return this.fixMergeSelection(
              Math.min(m_startRow,startRow),
              Math.min(m_startCol,startCol),
              Math.max(m_endRow,endRow),
              Math.max(m_endCol,endCol),
              merges.filter((m,j)=>i!=j)
            )
          }
        }
        return [startRow,startCol,endRow,endCol]
      },
      getNewCell(rowIndex,colIndex){
        const address = rowColToExcelAddress(rowIndex,colIndex)
        if(!this.newCells.has(address))
        {
          this.newCells.set(address,{address: address,__isNew:true, __rowIndex:rowIndex})
        }
        return this.newCells.get(address);
      },
      //判断是否可以编辑
      getIsEditable(cell){
        if(this.helper.table && this.helper.table.tag && this.helper.table.tag.isReadOnly)
        {
            return false;
        }
        if(cell.tag && cell.tag.isReadOnly){
            return false;
        }
        return true;
      }
    },
    render(h){
        return h( 'table',{
            class:'jtable-selection',
            ref:'root',
            on:{
              mousedown:this.mouseDown
            }
        },[
            h('tr',
            this.cols.map( (col,index) =>{ return h('td',{
                style: {
                    width: col.width,
                }
            }) })),
            this.rows.map( (row,rowIndex) => {
                return h('tr',{
                    style: {
                        height: row.height,
                    }
                },this.cols.map((col,colIndex) => {
                    let cell =  row.rowDef!=null && row.cells[colIndex+''] || this.getNewCell(rowIndex,colIndex) ;
                    this.allCells[cell.address] = cell;
                    const selection = this.helper.selection;
                    const merge = getMergeInside(rowIndex,colIndex,this.merges);
                    const has =  merge == null || (merge.startRow== rowIndex && merge.startCol == colIndex );
                    const isInSelection = (selection[0]<=rowIndex && selection[2]>=rowIndex 
                              && selection[1]<=colIndex && selection[3]>=colIndex)
                    let borderWidth=[0,0,0,0]

                    if(isInSelection){
                      //上边框：
                      borderWidth[0] = rowIndex == selection[0]?3:0;
                      //左边框
                      borderWidth[3] = colIndex == selection[1]?3:0;
                      //右边框
                      borderWidth[1] = (colIndex == selection[3] || (merge && merge.endCol==selection[3]))?3:0;
                      //下边框
                      borderWidth[2] = (rowIndex == selection[2] || (merge && merge.endRow==selection[2]))?3:0;
                    }
                    borderWidth = borderWidth.map(t=>t+'px').join(' ')
                    return !has ? null :
                        h('td',{
                        attrs:{
                            colspan: (merge && merge.startRow== rowIndex && merge.startCol == colIndex ) ? merge.endCol - merge.startCol + 1 : null,
                            rowspan: (merge && merge.startRow== rowIndex && merge.startCol == colIndex ) ? merge.endRow - merge.startRow + 1 : null,
                        },
                        on:{
                          mousedown:(event)=>{
                            if(this.startCell !== cell || this.endCell !==cell){
                              this.startCell = cell;
                              this.endCell = cell;
                            }
                            event.preventDefault();
                          },
                          mousemove:()=>{
                            if(this.mouseIsDown && this.endCell !== cell){
                              this.endCell = cell;
                            }
                          },
                          dblclick:()=>{
                            if(!this.getIsEditable(cell)){
                              return;
                            }

                            if(cell && cell.__isNew){
                              cell = this.helper.addNewCell(cell.address)
                            }
                            //等待 cell 重新渲染，会有cell.tag等附加内容
                            this.$nextTick(()=>{
                              if(cell.tag && cell.tag.inst && cell.tag.inst.beforeCellDoubleClickHook){                              
                                const result = cell.tag.inst.beforeCellDoubleClickHook()
                                if(!result)
                                {
                                  return;
                                }
                              }
                              this.helper.setEdittingCell(cell);
                              this.CellDoubleClick(cell);                           
                            })
                          }
                        },
                        style: {
                            width: this.cols[colIndex].width,
                            position:'relative',
                        }
                    },[
                      h('div',{
                        style:{
                          width:'100%',
                          height:'100%',
                          position:'absolute',
                          top:'0px',
                          left:'0px',
                          bottom:'0px',
                          right:'0px',
                          boxSizing: 'border-box',
                          background:isInSelection?(cell===this.startCell?"none":"rgba(0, 0, 12, 0.1)"):"#00000000",
                          opacity: 1,
                          border: isInSelection?'3px solid #109968':'none',
                          borderWidth:isInSelection?borderWidth:"none"
                        }
                      })
                    ])
                }));
            })
        ])  
    }
}
</script>

<style scoped>
.jtable-selection{
    box-sizing: 'border-box';
    width: fit-content;
}
table{
    margin:0;
    padding:0;
    border:none;
    border-collapse: collapse;
    overflow: hidden;
    table-layout: fixed
}
td{
    padding:0;
    margin:0;
}
</style>